/* libfake437 - a library for the rendering of code page 437 `graphics'
 * Copyright (C) 2008 Jack Kelly <endgame.dos@gmail.com>
 *
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#ifdef HAVE_STRING_H
#  include <string.h>
#endif
#include <SDL.h>
#include "fake437.h"

static inline int inside(FAKE437 *fake437, Uint16 x, Uint16 y){
  return ((x < fake437->width) && (y < fake437->height));
}

void f437_SetChar(FAKE437 *fake437, Uint16 x, Uint16 y, Uint8 ch){
  if(!inside(fake437, x, y)) return;
  if(fake437->cells[F437_INDEX(fake437, x, y)].ch != ch){
    fake437->cells[F437_INDEX(fake437, x, y)].ch = ch;
    F437_DIRTY(fake437, x, y) = 1;
  }
}

void f437_SetForeground(FAKE437 *fake437, Uint16 x, Uint16 y, Uint8 fg){
  if(!inside(fake437, x, y)) return;
  if(fake437->cells[F437_INDEX(fake437, x, y)].fg != fg){
    fake437->cells[F437_INDEX(fake437, x, y)].fg = fg;
    F437_DIRTY(fake437, x, y) = 1;
  }
}

void f437_SetBackground(FAKE437 *fake437, Uint16 x, Uint16 y, Uint8 bg){
  if(!inside(fake437, x, y)) return;
  if(fake437->cells[F437_INDEX(fake437, x, y)].bg != bg){
    fake437->cells[F437_INDEX(fake437, x, y)].bg = bg;
    F437_DIRTY(fake437, x, y) = 1;
  }
}

void f437_SetCharColor(FAKE437 *fake437, Uint16 x, Uint16 y,
		       Uint8 ch, Uint8 fg, Uint8 bg){
  f437_SetChar(fake437, x, y, ch);
  f437_SetForeground(fake437, x, y, fg);
  f437_SetBackground(fake437, x, y, bg);
}

static void markalldirty(FAKE437 *fake437){
  int x;
  int y;
  for(y = 0 ; y < fake437->height ; y++)
    for(x = 0 ; x < fake437->width ; x++)
      F437_DIRTY(fake437, x, y) = 1;
}

void f437_SetCharDef(FAKE437 *fake437, Uint8 ch, const char *newCh){
  int x;
  int y;
  strncpy(fake437->chars[ch], newCh, (F437_CHAR_WIDTH / 4) * F437_CHAR_HEIGHT);
  for(y = 0 ; y < fake437->height ; y++)
    for(x = 0 ; x < fake437->width ; x++)
      if(fake437->cells[F437_INDEX(fake437, x, y)].ch == ch)
	F437_DIRTY(fake437, x, y) = 1;
}

void f437_SetCharDefs(FAKE437 *fake437, f437_charDefs *chars){
  memcpy(&(fake437->chars), chars, sizeof(f437_charDefs));
  markalldirty(fake437);
}

void f437_SetColorDef(FAKE437 *fake437, Uint8 col, const SDL_Color *newCol){
  int x;
  int y;
  memcpy(&(fake437->colors[col]), newCol, sizeof(SDL_Color));
  for(y = 0 ; y < fake437->height ; y++)
    for(x = 0 ; x < fake437->width ; x++)
      if((fake437->cells[F437_INDEX(fake437, x, y)].fg == col) ||
	 (fake437->cells[F437_INDEX(fake437, x, y)].bg == col))
	F437_DIRTY(fake437, x, y) = 1;
}

void f437_SetColorDefs(FAKE437 *fake437, f437_colorDefs *colors){
  memcpy(&(fake437->colors), colors, sizeof(f437_colorDefs));
  markalldirty(fake437);
}
